package com.hp.bon.sgw.core.channel.handler;

import java.io.IOException;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.util.Date;

import org.apache.commons.lang.StringEscapeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.hp.bon.sgw.Constants;
import com.hp.bon.sgw.Constants.MessageType;
import com.hp.bon.sgw.bean.XmlMessage;
import com.hp.bon.sgw.core.BuzProcessorManager;
import com.hp.bon.sgw.core.CallParam;
import com.hp.bon.sgw.core.InprogressMessageQueue;
import com.hp.bon.sgw.core.channel.SoapChannel;
import com.hp.bon.sgw.domain.MessageDetail;
import com.hp.bon.sgw.service.SensitivtyCtrlService;
import com.hp.bon.sgw.threads.MessageDetailCacheManager;
import com.hp.bon.sgw.threads.TaskManager;
import com.hp.ocs.diameter.message.Message;

/**
 * @author sunhaiy
 * 
 */
public class BaseWSCallHandler implements IAsynCallHandler {
	private static final Logger logger = LoggerFactory.getLogger(BaseWSCallHandler.class);
	PrintStream printStream;

	public BaseWSCallHandler(PrintStream printStream) {
		this.printStream = printStream;
	}

	@Override
	public void onCallResult(CallParam callParam) {
		
		XmlMessage ack = null;
		Object response = null;

		if (callParam.getResponse() != null) {
			response = callParam.getResponse();
		} else if (callParam.getRecvResponse() != null) {
			response = callParam.getRecvResponse();
		}

		if (response == null) {
			ack = SoapChannel.createERRAnwser(callParam.getSessionId(), callParam.getRetCode() == 3002 ? 11202 : callParam.getRetCode(), callParam.getResultMsg());
		} else {
			if (response instanceof Message) {// CCA -> XML
				ack = BuzProcessorManager.getInstance().convertMessageToAck(callParam);
			} else if (response instanceof XmlMessage) {
				ack = (XmlMessage) response;
			} else {
				logger.warn("unknown response type:" + callParam.getResponse().getClass().getName());
			}
		}
		try {
			//敏感字段控制 add by yudan
			SensitivtyCtrlService.getInstance().checkSencitivtyCtrl(callParam, ack);
			String respXML = convertResponseString(ack);

			byte[] resp = respXML.getBytes("UTF-8");
			ack.setLength(resp.length);
			ack.setMsgTime(System.currentTimeMillis());
			printStream.write(resp);
			printStream.close();

			callParam.setResponse(ack);

			if (callParam.getRetCode() == Constants.ResultCode.SUCCESS) {// 成功的消息，请求应答入库

				MessageDetail detail = new MessageDetail();
				detail.setBusinessCallId(callParam.getBussinessCallId());
				detail.setSessionId(callParam.getSessionId());
				detail.setServiceContextId(callParam.getServiceContextId());
				detail.setMessageType(MessageType.WSA);
				detail.setDetails(ack.getDATA());
				detail.setMsgTime(new Date(ack.getMsgTime()));
				detail.setOpType("send");
				detail.setHostId(callParam.getUserName());
				MessageDetailCacheManager.getInstance().add(detail);
			}

			TaskManager.taskProcess(callParam);
			if (logger.isInfoEnabled()) {
				logger.info("http response  " + respXML);
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	// SOAP
	protected String convertResponseString(XmlMessage ack) {
		String orinData = ack.getDATA();
		String dataStr = "<![CDATA[" + orinData + "]]>";
		String errMsg = ack.getDS();
		errMsg = (errMsg != null) && (errMsg.indexOf('&') == -1) && (errMsg.indexOf('>') == -1) && (errMsg.indexOf('<') == -1) ? errMsg : StringEscapeUtils.escapeXml(errMsg);
		String respXML = "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"><SOAP-ENV:Header/><SOAP-ENV:Body><ns3:SgwQueryAck xmlns:ns3=\"http://www.chinatelecom.cn/SGW/SOAP\"><MID>" + ack.getMID() + "</MID><REPTAG>0</REPTAG><RTT>" + ack.getRTT() + "</RTT><SIG>"
				+ ack.getSIG() + "</SIG><RC>" + ack.getRC() + "</RC><DS>" + errMsg + "</DS><DATA>" + dataStr + "</DATA></ns3:SgwQueryAck></SOAP-ENV:Body></SOAP-ENV:Envelope>";
		return respXML;
	}

	@Override
	public int getProtocolType() {
		return Constants.SGW_GATEWAY_TYPE_WS;
	}
}
